{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "T0o1zHTnj6gZ"
      },
      "source": [
        "## 参考文档"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "c5UwQvnbRWo_"
      },
      "source": [
        "- https://cloud.baidu.com/qianfandev/topic/267899\n",
        "- https://python.langchain.com/v0.1/docs/integrations/llms/tongyi/"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZkNEwk4okEp9"
      },
      "source": [
        "## 安装相关模块"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Defaulting to user installation because normal site-packages is not writeable\n",
            "Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple\n",
            "Requirement already satisfied: python-dotenv in /Users/tanggaowei/Library/Python/3.9/lib/python/site-packages (1.0.1)\n",
            "\u001b[33mWARNING: You are using pip version 21.2.4; however, version 24.0 is available.\n",
            "You should consider upgrading via the '/Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip' command.\u001b[0m\n",
            "Note: you may need to restart the kernel to use updated packages.\n"
          ]
        }
      ],
      "source": [
        "%pip install python-dotenv"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "R86oaLjT4GO1",
        "outputId": "35a88589-3020-49ea-812b-9ab3d5f75559"
      },
      "outputs": [],
      "source": [
        "%pip install --upgrade langchain\n",
        "%pip install --upgrade langchain_community\n",
        "\n",
        "%pip install --upgrade --quiet  dashscope"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "Gj9wubLu4PH3",
        "outputId": "59cc1f0a-0640-411c-c5d5-388e422f2a69"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from pathlib import Path\n",
        "from dotenv import load_dotenv, find_dotenv\n",
        "\n",
        "# 加载环境变量，每次都覆盖旧数据\n",
        "env_path = Path('.') / 'test.env'\n",
        "load_dotenv(dotenv_path=env_path, override=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "StrcZYqxjN1N"
      },
      "source": [
        "> **test.env** 中保存了环境变量的值：\n",
        ">\n",
        "> ```\n",
        "> DASHSCOPE_API_KEY=sk-***\n",
        "> ```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "naBb6rYzkNga"
      },
      "source": [
        "## 初始化大语言模型对象"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 71
        },
        "id": "quRKSH6PFqfm",
        "outputId": "69abc5bc-f446-403f-a7f7-8f50b3d5580b"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'贾斯汀·比伯出生于1994年。在那一年，没有NFL球队赢得超级碗，因为超级碗在每年的2月份举行，而他是在3月1日出生的。不过，1993赛季的超级碗冠军是Dallas Cowboys（达拉斯牛仔队），他们在1994年2月6日赢得了第28届超级碗。'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import os\n",
        "from langchain_community.llms import Tongyi\n",
        "\n",
        "Tongyi().invoke(\"哪支NFL球队在贾斯汀·比伯出生的那一年赢得了超级碗?\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "coM1nT5XkrFO"
      },
      "source": [
        "## 使用大模型翻译文本"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Bo4t9orM4PQs",
        "outputId": "53c355d1-89e0-4463-f5d8-a16dbded401c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Translate the text into chinese.\n",
            "text: ```\n",
            "Arrr, I be fuming that me blender lid flew off and splattered me kitchen walls with smoothie! And to make matters worse,the warranty don't cover the cost of cleaning up me kitchen. I need yer help right now, matey!\n",
            "```\n",
            "\n",
            "啊，气死我了，我的搅拌机盖子飞掉，把果汁溅得到处都是，厨房墙壁都黏糊糊的！更糟糕的是，保修不包括清理厨房的费用。我现在需要你的帮助，伙计！\n"
          ]
        }
      ],
      "source": [
        "customer_email = \"\"\"\n",
        "Arrr, I be fuming that me blender lid \\\n",
        "flew off and splattered me kitchen walls \\\n",
        "with smoothie! And to make matters worse,\\\n",
        "the warranty don't cover the cost of \\\n",
        "cleaning up me kitchen. I need yer help \\\n",
        "right now, matey!\n",
        "\"\"\"\n",
        "language = \"chinese\"\n",
        "prompt = f\"\"\"Translate the text \\\n",
        "into {language}.\n",
        "text: ```{customer_email}```\n",
        "\"\"\"\n",
        "print(prompt)\n",
        "\n",
        "response = Tongyi().invoke(prompt)\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "INRW4icAPyCr"
      },
      "source": [
        "## 通过LangChain的方式来翻译文本"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "R86Bk31j4PWT",
        "outputId": "e85f4229-40d9-4c76-daae-6d7c2f94132d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "啊，我真是气坏了，我的搅拌机盖子飞了出去，把果汁溅得到处都是，厨房的墙壁都弄脏了！更糟糕的是，保修期不包括清理厨房的费用。我现在需要你的帮助，伙计！\n",
            "ああ、私はブレンド機の蓋が飛んでスムージーがキッチンの壁にまき散らされたことに怒っています！さらに問題を悪化させ的是、保証書はキッチンの清掃費用をカバーしていません。今すぐお手伝いが必要です、仲間よ！\n"
          ]
        }
      ],
      "source": [
        "from langchain.prompts import PromptTemplate\n",
        "\n",
        "llm = Tongyi()\n",
        "\n",
        "template = \"\"\"Translate the text \\\n",
        "into {language}. \\\n",
        "text: ```{text}```\n",
        "\"\"\"\n",
        "\n",
        "prompt = PromptTemplate.from_template(template)\n",
        "\n",
        "chain = prompt | llm\n",
        "\n",
        "language = \"chinese\"\n",
        "text = \"\"\"\n",
        "Arrr, I be fuming that me blender lid \\\n",
        "flew off and splattered me kitchen walls \\\n",
        "with smoothie! And to make matters worse, \\\n",
        "the warranty don't cover the cost of \\\n",
        "cleaning up me kitchen. I need yer help \\\n",
        "right now, matey!\n",
        "\"\"\"\n",
        "\n",
        "response = chain.invoke({\"language\": \"chinese\", \"text\": text})\n",
        "print(response)\n",
        "\n",
        "response = chain.invoke({\"language\": \"janpnese\", \"text\": text})\n",
        "print(response)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VeOGFZHrliPK"
      },
      "source": [
        "## 通过解析器来解析模型输出"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pRbnS7iNyviv"
      },
      "source": [
        "解析器的作用就是将一定格式的文本（例如json文本），解析成python对象（例如dict类型对象），以便进一步处理。\n",
        "\n",
        "**注意**：解析器并不是格式化文本的工具，它是将已经格式化的文本转化为python对象。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "NKcJRz3i4PcR"
      },
      "outputs": [],
      "source": [
        "customer_review = \"\"\"\\\n",
        "This leaf blower is pretty amazing.  It has four settings:\\\n",
        "candle blower, gentle breeze, windy city, and tornado. \\\n",
        "It arrived in two days, just in time for my wife's \\\n",
        "anniversary present. \\\n",
        "I think my wife liked it so much she was speechless. \\\n",
        "So far I've been the only one using it, and I've been \\\n",
        "using it every other morning to clear the leaves on our lawn. \\\n",
        "It's slightly more expensive than the other leaf blowers \\\n",
        "out there, but I think it's worth it for the extra features.\n",
        "\"\"\"\n",
        "\n",
        "review_template = \"\"\"\\\n",
        "For the following text, extract the following information:\n",
        "\n",
        "gift: Was the item purchased as a gift for someone else? \\\n",
        "Answer true if yes, false if not or unknown.\n",
        "\n",
        "delivery_days: How many days did it take for the product \\\n",
        "to arrive? If this information is not found, output -1.\n",
        "\n",
        "price_value: Extract any sentences about the value or price,\\\n",
        "and output them as a comma separated Python list.\n",
        "\n",
        "Format the output as JSON with the following keys, without \"```\":\n",
        "gift\n",
        "delivery_days\n",
        "price_value\n",
        "\n",
        "text: {text}\n",
        "\"\"\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "V1xPAF3ul6DJ",
        "outputId": "543f14a8-3e8b-4917-954b-afe06891a8a4"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "{\n",
            "  \"gift\": true,\n",
            "  \"delivery_days\": 2,\n",
            "  \"price_value\": [\"It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\"]\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "from langchain.prompts import ChatPromptTemplate\n",
        "\n",
        "prompt = ChatPromptTemplate.from_template(review_template)\n",
        "\n",
        "chain = prompt | llm\n",
        "\n",
        "response = chain.invoke({\"text\":customer_review})\n",
        "\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "LqjG4fDnl5_g"
      },
      "outputs": [],
      "source": [
        "from langchain.output_parsers import ResponseSchema, StructuredOutputParser"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "mLerNTFMl587"
      },
      "outputs": [],
      "source": [
        "# description 相当于字段的描述，不影响解析结果\n",
        "gift_schema = ResponseSchema(name=\"gift\",\n",
        "                             type=\"bool\",\n",
        "                             description=\"是否为礼物\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "8nHEUc2Ml56H"
      },
      "outputs": [],
      "source": [
        "delivery_days_schema = ResponseSchema(name=\"delivery_days\",\n",
        "                                       type=\"string\",\n",
        "                                       description=\"几天到货\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "AXC-OOoil50Q"
      },
      "outputs": [],
      "source": [
        "price_value_schema = ResponseSchema(name=\"price_value\",\n",
        "                                    type=\"string\",\n",
        "                                    description=\"价值或价格内容\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "OSNY7ab3l5pd",
        "outputId": "a9ac02c0-4638-4132-9b25-a55a23ac1c8b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The output should be a markdown code snippet formatted in the following schema, including the leading and trailing \"```json\" and \"```\":\n",
            "\n",
            "```json\n",
            "{\n",
            "\t\"gift\": bool  // 是否为礼物\n",
            "\t\"delivery_days\": string  // 几天到货\n",
            "\t\"price_value\": string  // 价值或价格内容\n",
            "}\n",
            "```\n"
          ]
        }
      ],
      "source": [
        "response_schemas = [gift_schema,delivery_days_schema,price_value_schema]\n",
        "output_parser = StructuredOutputParser.from_response_schemas(response_schemas)\n",
        "format_instructions = output_parser.get_format_instructions()\n",
        "print(format_instructions)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4yPciA05twRk",
        "outputId": "b2d71b71-e252-4051-88bb-010fb09d7f17"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "{\n",
            "  \"gift\": true,\n",
            "  \"delivery_days\": 2,\n",
            "  \"price_value\": [\"It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\"]\n",
            "}\n",
            "{'gift': True, 'delivery_days': 2, 'price_value': [\"It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\"]}\n"
          ]
        }
      ],
      "source": [
        "prompt = ChatPromptTemplate.from_template(template=review_template,format_instructions=format_instructions)\n",
        "\n",
        "chain = prompt | llm\n",
        "\n",
        "response = chain.invoke({\"text\":customer_review})\n",
        "\n",
        "print(response)\n",
        "# 将字符串格式化为 dict 类型变量\n",
        "output_dict = output_parser.parse(response)\n",
        "print(output_dict)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Om5A1tmMtwOh",
        "outputId": "44253dbf-6391-49b8-dec8-9245d61842d8"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "True\n"
          ]
        }
      ],
      "source": [
        "print(output_dict.get('gift'))"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
